home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / msysjour / vol06 / 04 / timer / tick.asm next >
Assembly Source File  |  1991-07-01  |  5KB  |  134 lines

  1. ;*****************************************************************************
  2. ;
  3. ;  A GetTickCount() that is accurate to the millisecond
  4. ;
  5. ;  Copyright (C) 1988-1991 Datametrics Systems Corporation
  6. ;
  7. ;  Notes:
  8. ;
  9. ;    - Proc directly accesses the 8254 timer chip (does port I/O).
  10. ;    - Proc issues sti/cli instructions.
  11. ;    - Assumes timer interrupt frequency has not been changed.
  12. ;    - There is a dramatic performance degradation if this proc
  13. ;      is executed on a 386 w/ I/O port trapping enabled for the
  14. ;      timer chip.
  15. ;    - Time will wrap after 49.7 days (1ms) or 4.97 days (100us).
  16. ;    - TIMERRES is 54925, the interrupt period in microseconds.
  17. ;
  18. ;*****************************************************************************
  19.  
  20. TENTHTICK EQU 0
  21.  
  22. if (TENTHTICK)
  23. TR1      EQU 16384              ;; (WORD)((TIMERRES*10*65536)/1000)
  24. TR2      EQU 549                ;; (TIMERRES*10/1000)
  25. TR3      EQU 8788               ;; (TIMERRES*10*16)/1000
  26. else
  27. TR1      EQU 60620              ;; (WORD)((TIMERRES*65536)/1000)
  28. TR2      EQU 54                 ;; (TIMERRES/1000)
  29. TR3      EQU 56243              ;; (TIMERRES*256*4)/1000
  30. endif
  31.  
  32. .MODEL SMALL,PASCAL
  33.         .DATA
  34. dwLowTickCount dd 0
  35.         .CODE
  36. GetLowTickCount PROC FAR USES SI DI
  37.         LOCAL   wFrac:WORD
  38.  
  39. ;       /*--- Disable interrupts; Issue read-back command for counter 0 ---*/
  40. start:  mov     al, 0C2h                ;; read back command
  41.         cli
  42.         out     43h, al                 ;; send command to 8254
  43.         jmp     short $+2               ;; I/O wait
  44.  
  45. ;       /*--- Set carry flag to counter 0 OUT pin status ---*/
  46.         in      al, 40h                 ;; OUT status is in bit 7
  47.         jmp     short $+2               ;; I/O wait
  48.         shl     al, 1                   ;; carry = OUT status
  49.  
  50. ;       /*--- Set CX to where in interval we are ---*/
  51.         in      al, 40h                 ;; read counter low
  52.         jmp     short $+2               ;; I/O wait
  53.         mov     cl, al                  ;; save counter low
  54.         in      al, 40h                 ;; read counter high
  55.         jmp     short $+2               ;; I/O wait
  56.         mov     ch, al                  ;; save counter high
  57.         jcxz    restart                 ;; restart if counter is zero
  58.         rcr     cx, 1                   ;; combine OUT status w/ counter
  59.         not     cx                      ;; change high->low to low->high
  60.  
  61. ;       /*--- Convert BIOS ticks to milliseconds (into DI:SI) ---*/
  62. if (?WIN EQ 1)
  63. extrn __0040H:ABS
  64.         mov     bx, __0040H             ;; Windows requires external absolute
  65. else
  66.         mov     bx, 040h                ;; ROM BIOS data area segment
  67. endif
  68.         mov     es, bx
  69.         mov     bx, 06Ch                ;; offset to timer info
  70.         mov     ax, TR1
  71.         mul     WORD PTR es:[bx]
  72.         mov     wFrac, ax               ;; fraction
  73.         mov     si, dx
  74.         mov     ax, TR1
  75.         mul     WORD PTR es:[bx+2]
  76.         mov     di, dx
  77.         add     si, ax
  78.         adc     di, 0
  79.         mov     ax, TR2
  80.         mul     WORD PTR es:[bx]
  81.         add     si, ax
  82.         adc     di, dx
  83.         mov     ax, TR2
  84.         mul     WORD PTR es:[bx+2]
  85.         add     di, ax
  86.  
  87. if (TENTHTICK)
  88. ;       /*--- Get tick count accurate to 1/10000 second ---*/
  89.         mov     ax, TR3
  90.         shr     cx, 1
  91.         shr     cx, 1
  92.         shr     cx, 1
  93.         shr     cx, 1
  94.         mul     cx                      ;; where in interval
  95.         add     ax, WORD PTR [wFrac]    ;; add fraction
  96.         mov     ax, si                  ;; ax = tick count low
  97.         adc     ax, dx
  98.         mov     dx, di                  ;; dx = tick count high
  99.         adc     dx, 0                   ;;
  100. else
  101. ;       /*--- Get tick count accurate to 1/1000 second ---*/
  102.         mov     ax, TR3
  103.         shr     cx, 1
  104.         shr     cx, 1
  105.         mul     cx                      ;; where in interval
  106.         add     ah, BYTE PTR [wFrac]    ;; add fraction low/high
  107.         adc     dl, BYTE PTR [wFrac+1]  ;; ..to get carry
  108.         mov     ax, si                  ;; ax = tick count low
  109.         adc     al, dh                  ;;
  110.         adc     ah, 0                   ;;
  111.         mov     dx, di                  ;; dx = tick count high
  112.         adc     dx, 0                   ;;
  113. endif
  114.  
  115. ;       /*--- Assure tick count is equal or advancing ---*/
  116.         cmp     dx, WORD PTR [dwLowTickCount+2]
  117.         ja      done
  118.         cmp     ax, WORD PTR [dwLowTickCount]
  119.         jb      restart
  120.  
  121. ;       /*--- Save last tick count obtained ---*/
  122. done:   mov     WORD PTR [dwLowTickCount], ax
  123.         mov     WORD PTR [dwLowTickCount+2], dx
  124.         sti
  125.         ret
  126.  
  127. ;       /*--- Restart procedure ---*/
  128. restart: sti
  129.          jmp    start
  130.  
  131. GetLowTickCount ENDP
  132.  
  133.         END
  134.